package com.sx.dao.daoImpl;

import com.sx.dao.PersonDao;
import com.sx.pojo.Person;
import com.sx.utils.DatabaseUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.*;
import java.util.ArrayList;

// 实现PersonDao接口
public class PersonDaoImpl implements PersonDao {
    // 日志
    private static final Logger logger = LogManager.getLogger(PersonDaoImpl.class);

    /**
     * 根据学生代码和密码查找用户
     * 此方法用于验证用户身份，通过匹配数据库中的用户名和密码来实现
     *
     * @param username 学生代码，用于标识用户
     * @param password 用户密码，用于验证身份
     * @return 如果找到匹配的用户，则返回Person对象；否则返回null
     * @throws SQLException 如果数据库操作失败，抛出此异常
     */
    @Override
    public Person findUserByStuCodeAndPassword(String username, String password) throws SQLException {
        // 连接数据库
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Person person = null;

        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            // SQL查询语句
            String sql = "select * from person where id=? and password=?";
            // 检查连接是否成功
            if (connection != null) {
                // 准备SQL语句
                statement = connection.prepareStatement(sql);
                // 设置查询参数
                statement.setString(1, username);
                statement.setString(2, password);
                // 执行查询
                resultSet = statement.executeQuery();

                // 处理查询结果
                if (resultSet.next()) {
                    // 初始化 person 对象
                    person = new Person();
                    // 设置person对象属性
                    person.setId(resultSet.getString("id"));
                    person.setPassword(resultSet.getString("password"));
                    person.setName(resultSet.getString("name"));
                    person.setAge(resultSet.getInt("age"));
                    person.setAuthorityLevel(resultSet.getInt("authorityLevel"));
                    // 记录日志
                    logger.info("查询到用户：{}", person);
                }
            }
        } catch (SQLException e) {
            // 记录数据库操作异常
            logger.error("数据库操作异常", e);
            // 抛出异常
            throw e;
        } finally {
            // 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                // 记录关闭资源异常
                logger.error("关闭资源异常", e);
            }
        }

        // 返回查询结果
        return person;
    }

    /**
     * 重写getAllPerson方法以获取所有人员信息
     * 此方法连接数据库，查询person表中的所有记录，并将结果映射到Person对象列表中
     *
     * @return 包含所有人员信息的ArrayList
     * @throws RuntimeException 如果数据库操作失败
     */
    @Override
    public ArrayList<Person> getAllPerson() {
        // 连接数据库
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Person person;
        ArrayList<Person> persons = new ArrayList<>();
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL查询
                String sql = "select * from person";
                statement = connection.prepareStatement(sql);
                // 执行查询并获取结果集
                resultSet = statement.executeQuery();
                // 遍历结果集，创建Person对象并填充到列表中
                while (resultSet.next()) {
                    person = new Person();
                    person.setId(resultSet.getString("id"));
                    person.setPassword(resultSet.getString("password"));
                    person.setName(resultSet.getString("name"));
                    person.setAge(resultSet.getInt("age"));
                    person.setAuthorityLevel(resultSet.getInt("authorityLevel"));
                    persons.add(person);
                }
            }
        } catch (SQLException e) {
            // 记录数据库操作异常并抛出运行时异常
            logger.error("数据库操作异常", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                // 记录关闭资源异常
                logger.error("关闭资源异常", e);
            }
        }
        // 返回包含所有人员信息的列表
        return persons;
    }

    /**
     * 根据学生代码查找用户
     * 此方法通过数据库查询来判断给定的学生代码是否对应一个已存在的用户
     *
     * @param id 学生代码，用于数据库查询
     * @return boolean 表示查询结果如果找到对应用户，则返回true；否则返回false
     */
    @Override
    public boolean findUserByStuCode(String id) {
        // 连接数据库
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        boolean flag = false;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL查询
                String sql = "select * from person where id=?";
                statement = connection.prepareStatement(sql);
                // 设置查询参数
                statement.setString(1, id);
                // 执行查询
                resultSet = statement.executeQuery();
                // 检查查询结果
                if (resultSet.next()) {
                    flag = true;
                }
            } else {
                // 记录数据库连接失败错误
                logger.error("数据库连接失败");
            }
        } catch (SQLException e) {
            // 记录数据库操作异常错误
            logger.error("数据库操作异常", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                // 记录关闭资源异常
                logger.error("关闭资源异常", e);
            }
        }
        // 返回查询结果
        return flag;
    }

    /**
     * 添加个人信息到数据库
     *
     * @param person 要添加的个人信息对象
     * @return 如果添加成功返回true，否则返回false
     */
    @Override
    public boolean addPerson(Person person) {
        // 连接数据库
        Connection connection;
        PreparedStatement statement;
        boolean flag = false;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL查询
                String sql = "insert into person(id,password,name,age,authorityLevel) values(?,?,?,?,?)";
                statement = connection.prepareStatement(sql);
                // 设置查询参数
                statement.setString(1, person.getId());
                statement.setString(2, person.getPassword());
                statement.setString(3, person.getName());
                statement.setInt(4, person.getAge());
                statement.setInt(5, person.getAuthorityLevel());
                // 执行更新操作
                int i = statement.executeUpdate();
                if (i > 0) {
                    // 如果更新影响了数据库，表示添加成功
                    flag = true;
                } else {
                    // 记录添加失败的日志
                    logger.error("添加失败");
                }
            } else {
                // 记录数据库连接失败的日志
                logger.error("数据库连接失败");
            }
        } catch (SQLException e) {
            // 记录数据库操作异常错误
            logger.error("数据库操作异常", e);
            throw new RuntimeException(e);
        }
        return flag;
    }

    /**
     * 删除员工
     * 根据员工ID删除数据库中的员工记录
     * 此方法首先尝试与数据库建立连接，然后执行删除操作
     * 如果删除成功，返回true；否则，返回false
     *
     * @param id 员工ID，用于标识要删除的员工
     * @return boolean 表示删除操作是否成功的布尔值
     */
    @Override
    public boolean deletePersonById(String id) {
        Connection connection;
        PreparedStatement statement;
        boolean flag = false;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL删除语句
                String sql = "delete from person where id =?";
                statement = connection.prepareStatement(sql);
                // 设置删除语句的参数
                statement.setString(1, id);
                // 执行删除操作
                int i = statement.executeUpdate();
                // 记录删除操作的结果
                logger.info("人员删除状态：{}", i);
                // 根据删除结果更新标志
                if (i > 0) {
                    flag = true;
                }
            }
        } catch (SQLException e) {
            // 处理数据库操作异常
            logger.error("数据库操作异常", e);
            // e.printStackTrace();
        }
        // 返回删除操作的结果
        return flag;
    }


    /**
     * 修改用户信息
     * 该方法用于更新数据库中的用户记录，根据提供的用户对象中的ID，
     * 更新该用户的密码、姓名、年龄和权限级别
     *
     * @param person 包含更新信息的用户对象，必须包含ID以确定要更新的记录
     * @return boolean 表示更新操作是否成功。返回true如果更新成功，否则返回false
     * @throws SQLException 如果数据库更新操作失败，抛出此异常
     */
    @Override
    public boolean updatePerson(Person person) {
        Connection connection = null;
        PreparedStatement statement = null;
        boolean flag = false;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL更新语句，确保根据ID更新其他字段
                String sql = "update person set password =?, name =?, age =?, authorityLevel =? where id =?";
                statement = connection.prepareStatement(sql);
                // 设置SQL语句参数
                statement.setString(1, person.getPassword());
                statement.setString(2, person.getName());
                statement.setInt(3, person.getAge());
                statement.setInt(4, person.getAuthorityLevel());
                statement.setString(5, person.getId());
                // 执行更新操作
                int i = statement.executeUpdate();
                if (i > 0) {
                    // 更新成功
                    flag = true;
                }
            }
        } catch (SQLException e) {
            // 记录数据库操作错误
            logger.error("执行数据库更新操作失败，SQL语句: {}", statement, e);
        } finally {
            // 关闭资源
            try {
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                // 记录关闭资源时的错误
                logger.error("关闭数据库资源出现异常", e);
            }
        }
        return flag;
    }

    /**
     * 根据ID获取Person对象
     * 此方法通过数据库查询来获取与给定ID对应的Person对象
     * 它首先建立数据库连接，然后执行查询操作，并将结果转换为Person对象
     *
     * @param id 用于查询的Person ID
     * @return 对应ID的Person对象，如果找不到则返回null
     */
    @Override
    public Person getPersonById(String id) {
        // 定义数据库连接，预编译语句和结果集变量
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        // 根据ID查询到的Person对象
        Person person = null;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            // 检查是否成功获取数据库连接
            if (connection != null) {
                // 准备SQL查询语句
                String sql = "select * from person where id =?";
                // 创建预编译语句对象
                statement = connection.prepareStatement(sql);
                // 设置查询语句参数
                statement.setString(1, id);
                // 执行查询并获取结果集
                resultSet = statement.executeQuery();
                // 检查查询结果是否非空
                if (resultSet.next()) {
                    // 根据查询结果创建Person对象
                    person = new Person(resultSet.getString("id"), resultSet.getString("password"), resultSet.getString("name"), resultSet.getInt("age"), resultSet.getInt("authorityLevel"));
                }
                // 记录查询到的用户信息
                logger.info("查询到用户信息：{}", person);
            } else {
                // 如果数据库连接失败，记录错误信息
                logger.error("数据库连接失败");
            }
        } catch (SQLException e) {
            // 记录执行查询操作失败的错误信息，并抛出运行时异常
            logger.error("执行数据库查询操作失败，SQL语句: {}", statement, e);
            throw new RuntimeException(e);
        } finally {
            // 关闭数据库资源
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                // 如果关闭数据库资源时出现异常，记录错误信息
                logger.error("关闭数据库资源出现异常", e);
            }
        }
        // 返回查询到的Person对象
        return person;
    }

    /**
     * 根据ID获取人员姓名
     * 此方法通过数据库查询来获取对应ID的人员姓名
     *
     * @param id 人员的唯一标识符
     * @return 如果找到对应的人员，则返回人员的姓名；否则返回null
     */
    @Override
    public String getPersonNameById(String id) {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            // 获取数据库连接
            conn = DatabaseUtil.getConnection();
            if (conn != null) {
                // 准备SQL查询
                String sql = "SELECT name FROM person WHERE id = ?";
                stmt = conn.prepareStatement(sql);
                stmt.setString(1, id);
                // 执行查询
                rs = stmt.executeQuery();
                // 处理查询结果
                if (rs.next()) {
                    return rs.getString("name");
                }
            } else {
                // 记录数据库连接失败的错误
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 记录数据库操作异常
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭数据库资源
            try {
                if (rs != null) {
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                // 记录关闭资源时的异常
                logger.error("关闭资源异常", e);
            }
        }
        // 如果没有找到对应的人员姓名，则返回null
        return null;
    }
}

